
#include "Terrain.h"
#include "Mesh.h"

Terrain *terrain = 0;

//
// Constructor
//

Terrain::Terrain(SceneNode *parent)
{
	node = parent->createChildSceneNode("Terrain");

	// Initialize vertices & dim
	verts.push_back(std::vector<double>(1));

	width = 1;
	height = 1;

	nodesWidth = 1;
	nodesHeight = 1;
}

//
// Create
//

void Terrain::Create(bool forceRedraw)
{
	if(!Update() && !forceRedraw)
		return;

	double dWidth = width / (nodesWidth-1);
	double dHeight = height / (nodesHeight-1);
	double w = width * -0.5;

	uint a = 0;

	std::vector<Vector3> vertices;
	std::vector<Vector3i> triangles;

	fori(nodesWidth)
	{
		double h = height * -0.5;
		uint b = 0;

		forj(nodesHeight)
		{
			vertices.push_back(Vector3(h, w, verts[a][b]));

			h += dHeight;
			b++;
		}

		w += dWidth;
		a++;
	}

	fori(nodesWidth-1)
	{
		uint a = i*nodesWidth;
		forj(nodesHeight-1)
		{
			triangles.push_back(Vector3i(a+j, a+j+1, a+nodesWidth));
			triangles.push_back(Vector3i(a+nodesWidth, a+j+1, a+nodesWidth+1));
		}
	}

	Entity *entity = CreateMesh(vertices, triangles);

	node->detachAllObjects();
	node->attachObject(entity);
}

//
// Update
//

bool Terrain::Update()
{
	uint h = verts.size();
	uint w = verts[0].size();

	bool changed = false;

	if(h != nodesHeight)
	{
		if(h < nodesHeight)
			fori(nodesHeight-h)
				verts.push_back(std::vector<double>(nodesWidth));
		else
			verts.resize(nodesHeight);

		changed = true;
	}
	
	if(w != nodesWidth)
	{
		uint _h = min(h, nodesHeight);

		fori(_h)
			verts[i].resize(nodesWidth);

		changed = true;
	}

	return changed;
}